// 规范化测试脚本：参考 test-code-*.js 风格
const http = require("http");
const WebSocket = require("ws");

const CONFIG = {
  server: { host: "localhost", port: 3000, protocol: "http" },
  testUser: {
    mobile: "17091279999",
    passwordHash: "e10adc3949ba59abbe56e057f20f883e", // 123456
  },
};

function sleep(ms) { return new Promise((r) => setTimeout(r, ms)); }

function httpRequest(path, method = "GET", body = null) {
  const options = {
    hostname: CONFIG.server.host,
    port: CONFIG.server.port,
    path,
    method,
    headers: { "Content-Type": "application/json" },
  };
  return new Promise((resolve, reject) => {
    const req = http.request(options, (res) => {
      let data = "";
      res.on("data", (chunk) => (data += chunk));
      res.on("end", () => {
        try {
          const json = JSON.parse(data || "{}");
          if (res.statusCode >= 200 && res.statusCode < 300) resolve(json);
          else reject(new Error(json?.msg || `HTTP ${res.statusCode}`));
        } catch (e) { reject(new Error("响应解析失败")); }
      });
    });
    req.on("error", (err) => reject(err));
    if (body) req.write(JSON.stringify(body));
    req.end();
  });
}

async function ensureUserAndLogin() {
  try {
    await httpRequest("/user-service/user/register", "POST", {
      mobile: CONFIG.testUser.mobile,
      pwd: CONFIG.testUser.passwordHash,
      captcha: "123456",
    });
  } catch (e) {
    // 已存在则忽略
  }
  const login = await httpRequest("/user-service/user/login", "POST", {
    mobile: CONFIG.testUser.mobile,
    pwd: CONFIG.testUser.passwordHash,
  });
  if (login?.code !== 0) throw new Error(login?.msg || "登录失败");
  return { userId: login.data.userId, token: login.data.accessToken };
}

async function sendAndWait(ws, actId, payload = {}, timeoutMs = 8000) {
  return new Promise((resolve, reject) => {
    const timer = setTimeout(() => {
      ws?.off?.("message", handler);
      reject(new Error(`等待 act_id=${actId} 响应超时`));
    }, timeoutMs);
    const handler = (raw) => {
      try {
        const msg = JSON.parse(raw.toString());
        if (msg && msg.act_id === actId) {
          clearTimeout(timer);
          ws.off("message", handler);
          resolve(msg);
        }
      } catch {}
    };
    ws.on("message", handler);
    ws.send(JSON.stringify({ c: actId, d: Object.keys(payload).length ? payload : null }));
  });
}

async function run() {
  const { token } = await ensureUserAndLogin();
  const wsUrl = `ws://${CONFIG.server.host}:${CONFIG.server.port}/user-service/websocket?t=${token}`;
  const ws = new WebSocket(wsUrl);
  await new Promise((r) => ws.on("open", r));
  console.log("✅ WebSocket connected");

  // 查询角色列表 (3)
  const list = await sendAndWait(ws, 3, {});
  let roleId = list?.roleList?.[0]?.id;
  if (!roleId) {
    // 创建角色 (5 with d)
    await ws.send(JSON.stringify({ c: 5, d: { name: "房屋测试", sex: 1, roleType: 1, headIndex: 2 } }));
    await sleep(500);
    const list2 = await sendAndWait(ws, 3, {});
    roleId = list2?.roleList?.[0]?.id;
  }

  // 选择角色 (4)
  await sendAndWait(ws, 4, { characterId: roleId });

  // 请求 1480
  const res = await sendAndWait(ws, 1480, {});
  console.log("📨 1480:", JSON.stringify(res));

  // 简单断言：允许 code=0 且 data 有 lvl / 或 code=8 未购买
  if (res.code === 0) {
    if (!res.data || typeof res.data.lvl === "undefined") throw new Error("返回缺少必需字段 lvl");
  } else if (res.code === 8) {
    // 允许未购房
  } else {
    throw new Error(`返回错误: code=${res.code} msg=${res.msg}`);
  }

  ws.close();
  console.log("✅ 1480 测试通过");
}

run().catch((e) => {
  console.error("❌ Test failed:", e.message || e);
  process.exit(1);
});


